﻿using Microsoft.EntityFrameworkCore;
using mozhi.smarterp.AuthorCenter.Enums;
using mozhi.smarterp.AuthorCenter.Users.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Identity;
using Volo.Abp.Identity.EntityFrameworkCore;

namespace mozhi.smarterp.AuthorCenter.Users
{
    [ExposeServices(typeof(ICustomIdentityUserRepository), IncludeDefaults = true)]
    public class CustomIdentityUserRepository : EfCoreIdentityUserRepository, ICustomIdentityUserRepository
    {
        public CustomIdentityUserRepository(IDbContextProvider<IIdentityDbContext> dbContextProvider) : base(dbContextProvider)
        {
        }

        public async Task<long> GetCountAsync(string filter = null, List<UserType> types = null, CancellationToken cancellationToken = default)
        {
            return await((IQueryable<IdentityUser>)(await GetDbSetAsync().ConfigureAwait(continueOnCapturedContext: false)))
                .WhereIf(!filter.IsNullOrWhiteSpace(), (Expression<Func<IdentityUser, bool>>)((IdentityUser u) => u.UserName.Contains(filter) || u.Email.Contains(filter) || (u.Name != null && u.Name.Contains(filter)) || (u.Surname != null && u.Surname.Contains(filter)) || (u.PhoneNumber != null && u.PhoneNumber.Contains(filter))))
                .WhereIf(types != null, x => types.Contains(EF.Property<UserType>(x, "UserType")))
                .LongCountAsync(GetCancellationToken(cancellationToken))
                .ConfigureAwait(continueOnCapturedContext: false);
        }

   
        public async Task<List<IdentityUser>> GetListAsync(string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, string filter = null, bool includeDetails = false, List<UserType> types = null, CancellationToken cancellationToken = default)
        {
            return await(await GetDbSetAsync().ConfigureAwait(continueOnCapturedContext: false)).IncludeDetails(includeDetails).WhereIf(!filter.IsNullOrWhiteSpace(), (IdentityUser u) => u.UserName.Contains(filter) || u.Email.Contains(filter) || (u.Name != null && u.Name.Contains(filter)) || (u.Surname != null && u.Surname.Contains(filter)) || (u.PhoneNumber != null && u.PhoneNumber.Contains(filter)))
                 
                 .WhereIf(types != null, x => types.Contains(EF.Property<UserType>(x, "UserType")))
                 .OrderBy<IdentityUser>(sorting.IsNullOrWhiteSpace() ? "UserName" : sorting)
                 .PageBy(skipCount, maxResultCount)
                 .ToListAsync(GetCancellationToken(cancellationToken))
                 .ConfigureAwait(continueOnCapturedContext: false);
        }
    }
}
